package com.istock.union.user.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.istock.base.cache.BaseCacheManager;
import com.istock.base.serializer.json.TypeReference;
import com.istock.union.user.service.StorageService;

public class BaseCacheStorageService implements StorageService {

	@Autowired
	private BaseCacheManager cacheManager;
	
	private Long defaultExpireTime = 1800L;
	
	public void setDefaultExpireTime(Long defaultExpireTime) {
		this.defaultExpireTime = defaultExpireTime;
	}

	public void setBaseCacheManager(BaseCacheManager cacheManager) {
		this.cacheManager = cacheManager;
	}
	
	//存储每个token,在调用缓存服务的时候,存储的key
	private Map<String , Set<String>> keyMap = new ConcurrentHashMap<String , Set<String>>();
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	private void putKey(String token , String key){
		Set<String> keySet = keyMap.get(token);
		if(keySet == null){
			keySet = new HashSet<String>();
		}
		keySet.add(key);
		if(!keyMap.containsKey(token)){
			keyMap.put(token, keySet);
		}
	}
	
	private void removeKey(String token , String key){
		Set<String> keySet = keyMap.get(token);
		if(keySet != null){
			keySet.remove(key);
			if(keySet.isEmpty()) {
				keyMap.remove(token);
			}
		}
	}
	
	@Override
	public <T> T getObject(String token, String key, TypeReference<T> typeReference) {
		return (T)cacheManager.queryObjectAndTouch(token+key, typeReference.getType(),defaultExpireTime);
	}

	@Override
	public void putObject(String token, String key, Object obj) {
		putObject(token,key , obj , defaultExpireTime);
	}

	@Override
	public void putObject(String token, String key, Object obj, Long expireSecond) {
		if(StringUtils.isNotBlank(token)){
			putKey(token,key);
		}
		logger.debug("==========before put token:{} , key:{} ,obj:{}}" , new Object[]{token , key , obj});
		cacheManager.updateCache(token+key, obj, TimeUnit.SECONDS.toSeconds(expireSecond));
	}

	@Override
	public void removeObject(String token, String key) {
		if(StringUtils.isNotBlank(token)){
			removeKey(token, key);
		}
		logger.debug("==========before remove token:{} , key:{}}" , new Object[]{token , key});
		cacheManager.removeCacheKey(token+key);
	}

	@Override
	public void removeAll(String token) {
		if(StringUtils.isNotBlank(token)){
			Set<String> keySet = keyMap.get(token);
			List<String> keyList = new ArrayList<String>(keySet);
			if(keyList != null && !keyList.isEmpty()){
				for(String key : keyList){
//					cacheManager.removeCacheKey(token+key);
					removeObject(token , key);
				}
			}
		}
	}

}
